#nullable enable
namespace Application.Service.Auth;

/// <summary>
/// 会话管理器服务
/// <para>功能：管理用户登录会话，包括创建、验证、移除会话，以及强制注销用户</para>
/// <list type="bullet">
/// <item><description>维护会话ID与用户ID的双向映射关系</description></item>
/// <item><description>确保会话的唯一性和安全性</description></item>
/// <item><description>提供会话状态查询和管理功能</description></item>
/// <item><description>处理会话超时和强制注销</description></item>
/// </list>
/// </summary>
public class SessionManagerService: ISingleton
{
    /// <summary>
    /// 会话ID到用户ID的映射字典
    /// <para>功能：用于通过会话ID查找对应的用户ID</para>
    /// <para>用途：验证会话有效性时快速查找用户信息</para>
    /// </summary>
    private readonly ConcurrentDictionary<string, int> _sessionUsers = new();
    
    /// <summary>
    /// 用户ID到会话ID的映射字典
    /// <para>功能：用于通过用户ID查找对应的会话ID</para>
    /// <para>用途：检查用户是否已登录时快速查找会话信息</para>
    /// </summary>
    private readonly ConcurrentDictionary<int, string> _userSessions = new();
    
        
    /// <summary>
    /// 检查用户是否已登录
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <returns>返回用户当前登录状态（true表示已登录，false表示未登录）</returns>
    public bool IsUserLoggedIn(int userId)
    {
        return _userSessions.ContainsKey(userId);
    }
    
    /// <summary>
    /// 获取用户的会话ID
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <returns>返回用户的会话ID或null（如果用户未登录则返回null）</returns>
    public string? GetUserSessionId(int userId)
    {
        return _userSessions.TryGetValue(userId, out var sessionId) ? sessionId : null;
    }
    
    /// <summary>
    /// 通过会话ID获取用户ID
    /// </summary>
    /// <param name="sessionId">会话ID</param>
    /// <returns>返回用户ID或null（如果会话无效则返回null）</returns>
    public int? GetUserIdBySessionId(string sessionId)
    {
        return _sessionUsers.TryGetValue(sessionId, out var userId) ? userId : null;
    }
    
    /// <summary>
    /// 为用户创建新的会话并建立双向映射关系
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <param name="sessionId">会话ID</param>
    /// <returns>是否成功创建会话并建立双向映射关系</returns>
    public bool CreateSession(int userId, string sessionId)
    {
        // 1. 检查用户是否已有活跃会话（防止重复登录）
        if (_userSessions.ContainsKey(userId))
        {
            Log.Warning($"用户 {userId} 已有会话，无法创建新会话");
            return false;
        }

        // 2. 检查会话ID是否已存在（确保会话ID唯一性）
        if (_sessionUsers.ContainsKey(sessionId))
        {
            Log.Warning($"会话ID {sessionId} 已存在，无法创建会话");
            return false;
        }

        // 3. 添加双向映射关系：用户ID->会话ID 和 会话ID->用户ID
        if (!_userSessions.TryAdd(userId, sessionId) || !_sessionUsers.TryAdd(sessionId, userId))
        {
            Log.Error($"创建用户 {userId} 的会话失败");
            return false;
        }

        // 4. 记录会话创建成功日志
        Log.Information($"为用户 {userId} 创建会话成功，会话ID: {sessionId}");
        return true;
    }
    
    /// <summary>
    /// 通过会话ID终止用户会话并清理相关映射
    /// </summary>
    /// <param name="sessionId">会话ID</param>
    /// <returns>是否成功移除会话并清理双向映射关系</returns>
    public bool RemoveSession(string sessionId)
    {
        // 1. 通过会话ID获取对应的用户ID
        if (!_sessionUsers.TryGetValue(sessionId, out var userId))
        {
            Log.Warning($"会话ID {sessionId} 不存在，无法移除");
            return false;
        }

        // 2. 移除双向映射关系
        var removedFromSession = _sessionUsers.TryRemove(sessionId, out _);
        var removedFromUser = _userSessions.TryRemove(userId, out _);

        // 3. 检查移除操作是否成功
        if (removedFromSession && removedFromUser)
        {
            Log.Information($"会话 {sessionId} 移除成功，用户ID: {userId}");
            return true;
        }
        else
        {
            Log.Error($"会话 {sessionId} 移除失败，用户ID: {userId}");
            return false;
        }
    }
    
    /// <summary>
    /// 清理指定用户的所有会话信息
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <returns>是否成功移除用户的所有会话记录</returns>
    public bool RemoveUserSessions(int userId)
    {
        if (_userSessions.TryRemove(userId, out var sessionId))
        {
            _sessionUsers.TryRemove(sessionId, out _);
            return true;
        }
        
        return false;
    }
    
    /// <summary>
    /// 管理员强制终止指定用户的会话
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <returns>是否成功强制注销用户的所有会话记录</returns>
    public bool ForceLogout(int userId)
    {
        // 1. 获取用户的会话ID
        if (!_userSessions.TryGetValue(userId, out var sessionId))
        {
            Log.Warning($"用户 {userId} 没有活跃会话，无法强制注销");
            return false;
        }

        // 2. 移除双向映射关系
        var removedFromUser = _userSessions.TryRemove(userId, out _);
        var removedFromSession = _sessionUsers.TryRemove(sessionId, out _);

        // 3. 检查操作结果
        if (removedFromUser && removedFromSession)
        {
            Log.Information($"已强制注销用户 {userId}，会话ID: {sessionId}");
            return true;
        }
        else
        {
            Log.Error($"强制注销用户 {userId} 失败");
            return false;
        }
    }
    
    /// <summary>
    /// 统计当前系统中活跃的会话总数
    /// </summary>
    /// <returns>返回当前活跃会话的数量</returns>
    public int GetActiveSessionCount()
    {
        return _userSessions.Count;
    }
    
    /// <summary>
    /// 获取当前系统中所有活跃用户的ID列表
    /// </summary>
    /// <returns>返回当前活跃用户的ID列表</returns>
    public List<int> GetActiveUserIds()
    {
        return _userSessions.Keys.ToList();
    }
}